package com.dhj.yygh.service.impl;

import com.cloopen.rest.sdk.CCPRestSmsSDK;
import com.dhj.yygh.common.exception.YyghException;
import com.dhj.yygh.service.RlySmsUService;
import com.dhj.yygh.vo.msm.MsmVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class RlySmsServiceImpl implements RlySmsUService {

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    private static Integer aliveTime = 1;// 有效期时间(分钟)

    // 容联云相关参数
    private static String accountSid = "8aaf07087955b4b501796327092a0638";
    private static String accountToken = "01e999da4b094102bb3831275ed959f8";
    private static String appId = "8aaf07087955b4b5017963270a4c063f";
    private static String code = "";// 用于保存随机生成的验证码

    // 用于保存发送短信后的结果
    private static HashMap<String, Object> sendResult;

    // 用于自定义封装最终返回结果
    private static Map<String, Object> resultMap = new HashMap<>();

    // 容联云 api 对象
    CCPRestSmsSDK restAPI;

    // 初始化 api 对象
    {
        restAPI = new CCPRestSmsSDK();
        // 初始化服务器地址和端口，生产环境配置成 app.cloopen.com，端口是 8883
        restAPI.init("app.cloopen.com", "8883");

        // 初始化主账号名称和主账号令牌，登陆云通讯网站后，可在控制首页中看到开发者主账号 ACCOUNT SID 和主账号令牌 AUTH TOKEN。
        restAPI.setAccount(accountSid, accountToken);

        // 请使用管理控制台中已创建应用的 APPID。
        restAPI.setAppId(appId);
    }

    /**
     * 根据手机号发送短信验证码
     *
     * @param phone 手机号
     * @return 返回发送结果 Map 集合
     */
    @Override
    public Map<String, Object> sendSms(String phone) {

        // 首先判断手机号是否为空
        if (StringUtils.isEmpty(phone)) {
            throw new YyghException("手机号为空!", 204);
        }

        // 判断 redis 中是否有该手机号对应的验证码
        String existCode = redisTemplate.opsForValue().get(phone);
        if (!StringUtils.isEmpty(existCode)) {
            // 如果有，返回短信未过期的提示信息
            resultMap.put("msg", "验证码未过期，稍后再试!");
            resultMap.put("sendState", false);// 是否发送成功
            return resultMap;
        }

        code = RandomStringUtils.randomNumeric(6);// 发送 6 位随机短信验证码

        /*
        设置需要发送的手机号和发送的验证码及过期时间
        参数1 手机号
        参数2 容联云的短信模板编号
        参数3 将 String[] 数组中对应索引位置的值替换到短信模板对应索引位置: {0} {1}
         */
        sendResult = restAPI.sendTemplateSMS(phone, "1", new String[]{code, aliveTime.toString()});


        /*
        TODO 根据返回的状态码判断是发送成功
         */

        if ("000000".equals(sendResult.get("statusCode"))) {
            /*
            将发送成功的验证码保存到 redis
            参数1 key
            参数2 value
            参数3 有效期时间值
            参数4 时间单位(分钟) minutes
             */
            redisTemplate.opsForValue().set(phone, code, aliveTime, TimeUnit.MINUTES);

            resultMap.put("sendState", true);// 是否发送成功
            resultMap.put("msg", "发送成功!");// 发送的验证码
            return resultMap;
        }

        // 封装错误信息
        resultMap.put("sendState", false);
        resultMap.put("msg", "发送失败!稍后再试");// 错误信息

        log.info((String) sendResult.get("statusMsg"));

        return resultMap;
    }

    /**
     * 监听 mq 发送短信
     *
     * @param msmVo 短信 vo
     * @return 返回是否发送成功
     */
    @Override
    public boolean sendMqSms(MsmVo msmVo) {

        String phone = msmVo.getPhone();

        String msg = (String) msmVo.getParam().get("msg");

        // 手机号是否为空
        if (StringUtils.isEmpty(phone)) {
            throw new YyghException("手机号为空!", 204);
        }

        sendResult = restAPI.sendTemplateSMS(phone, "1", new String[]{msg, aliveTime.toString()});

        // 根据返回的状态码判断是发送成功
        if ("000000".equals(sendResult.get("statusCode"))) {
            return true;
        }
        return false;
    }
}
